import java.awt.Point;
import java.util.ArrayList;


public class Profundidade {
	Problema prob;
	int l;
	
	public Profundidade(Problema _p) {
		prob = _p;
		l = 1;
		Estado estadoFinal = null;
		while(estadoFinal == null || !estadoFinal.equals(prob.estadoObjetivo)) {
			System.out.println("AUMENTA L=" + l);
			geraSucessores(prob.estadoInicial);
			estadoFinal = run();
			
			l++;
		} 
		
		//prints
		ArrayList<Estado> resultado = new ArrayList<>();
		
		while (estadoFinal.pai != null) {
			resultado.add(0, estadoFinal);
			estadoFinal = estadoFinal.pai;
		}
		
		for (Estado estado : resultado) {
			System.out.print(estado.p + "->");	
		}
	}
	
	public Estado run () {
		
		Estado melhorEstado = null;
		for (Estado n : prob.fronteira) {
			System.out.println("FRONT "+n.p+" -> prof="+n.profundidade+" g="+n.g);
		}
		
		for (Estado n : prob.fronteira) {
			if (melhorEstado == null || (n.profundidade < l && n.profundidade > melhorEstado.profundidade))
				melhorEstado = n;
			try {
				Thread.sleep(000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		if (melhorEstado != null && melhorEstado.equals(prob.estadoObjetivo))
			return melhorEstado;
		
		if ( melhorEstado.profundidade >= l)
			return melhorEstado;
			
		System.out.println(">>>"+melhorEstado.p);
		geraSucessores(melhorEstado);
		return run();
	}
	
	public void geraSucessores(Estado n) {
		// x: 0-3
		// y: 0-4
		
		if ((n.p.x + 1) <= 3) {
			Estado e = new Estado (new Point(n.p.x+1, n.p.y), n, prob);
			e.profundidade=n.profundidade+1;
			if (!prob.fronteira.contains(e) && !temBarreira(e))
				prob.fronteira.add(e);
		}
		if ((n.p.x - 1) >= 0) {
			Estado e = new Estado (new Point(n.p.x-1, n.p.y), n, prob);
			e.profundidade=n.profundidade+1;
			if (!prob.fronteira.contains(e) && !temBarreira(e))
				prob.fronteira.add(e);
		}
		if ((n.p.y + 1) <= 4) {
			Estado e = new Estado (new Point(n.p.x, n.p.y+1), n, prob);
			e.profundidade=n.profundidade+1;
			if (!prob.fronteira.contains(e) && !temBarreira(e))
				prob.fronteira.add(e);
		}
		if ((n.p.y - 1) >= 0) {
			Estado e = new Estado (new Point(n.p.x, n.p.y-1), n, prob);
			e.profundidade=n.profundidade+1;
			if (!prob.fronteira.contains(e) && !temBarreira(e))
				prob.fronteira.add(e);
		}
		
		if (!prob.fronteira.isEmpty())
			prob.fronteira.remove(n);
		
	}

	public boolean temBarreira(Estado n) {
		System.out.println("TESTANDO BARRERA "+n.pai.p+" -> "+n.p);
		for (int i=0; i<4; i++) {
			if ((prob.barreira[i][0].equals(n.pai.p) && prob.barreira[i][1].equals(n.p)) ||
					(prob.barreira[i][1].equals(n.pai.p) && prob.barreira[i][0].equals(n.p))) {
				System.out.println("BARREIRAAA "+n.pai.p+" -> "+n.p);
				return true;
			}
		}
		return false;
	}
	
	public double f(Estado n) {
		//f(n) = g(n)
		return n.g; //nao tem a heuristica
	}
}
